﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CompanySearchConsole;
using DSRSystemCore.Core;
using Nest;

namespace ElasticSearch.Tests
{
    public class CompanySync : ITestContext
    {
        ElasticClient _client;

        public CompanySync()
        {
            var uri = new Uri("http://localhost:9200/");
            var settings = new ConnectionSettings(uri, defaultIndex: "dsrsystem");

            this._client = new ElasticClient(settings);

        }

        public void Search(string text)
        {
            //~(apple.*)&(.*apple.*)
            var textToMatch = string.Format("\"{0}\"",text.Replace("\"", "\\\""));
           
            var startsWith = string.Format("{0}.*", textToMatch);
            var containsNotStartWith = string.Format("~({0}.*)&(.*{1}.*)", textToMatch, textToMatch);
           
            var query1 = this._client.Search<ESEntities.Company>(s => s
                .Index("dsrsystem")
                .SortAscending(sort => sort.Name)
                .Query(q => 
                    q.Regexp(
                        (f) => f.Value(startsWith).OnField(onF => onF.Name)))
                .Take(20)
                );

            var query2 = this._client.Search<ESEntities.Company>(s => s
             .Index("dsrsystem")
             .SortAscending(sort => sort.Name)
             .Query(q =>
                 q.Regexp(
                     (f) => f.Value(containsNotStartWith).OnField(onF => onF.Name)))
             .Take(20)
             );


            
        }
        

        public void ImportAll()
        {

            using (var context = new DSRSystemEntities())
            {
                this._client.DeleteIndex(d => d.Index("dsrsystem"));

                this._client.CreateIndex("dsrsystem", c => c
                    .AddMapping<ESEntities.Company > (m => m.MapFromAttributes()));

                //var company = new ESEntities.Company { Id = Guid.NewGuid() };
                //company.Name = "aabc aa";
                //this._client.Index(company);

                //company = new ESEntities.Company { Id = Guid.NewGuid() };
                //company.Name = "bc aa";
                //this._client.Index(company);


                //company = new ESEntities.Company { Id = Guid.NewGuid() };
                //company.Name = "xct dd";
                //this._client.Index(company);

                //return;

                foreach (var dbCompany in context.Companies)
                {
                    var company = new ESEntities.Company { Id = dbCompany.CompanyId };
                    company.Name = dbCompany.Name.ToLowerInvariant();
                    company.WordifiedName = company.Name;
                    this._client.Index(company);
                }
             
                
            }
        }


        public CompanySearchConsole.MongoEntities.RawQueryResult TestRaw(string text, string discriminator, CompanySearchConsole.MongoEntities.Session session)
        {
            var testName = "raw_nameIndex";

            var queryResult = new CompanySearchConsole.MongoEntities.RawQueryResult { Name = testName, Session = session, Info = text };

           
            var textToMatch = string.Format("\"{0}\"",text.Replace("\"", "\\\""));
           
            var startsWith = string.Format("{0}.*", textToMatch);
            var containsNotStartWith = string.Format("~({0}.*)&(.*{1}.*)", textToMatch, textToMatch);


            Func<ISearchResponse<ESEntities.Company>> query1 = () => this._client.Search<ESEntities.Company>(s => s
                .Index("dsrsystem")
                .SortAscending(sort => sort.Name)
                .Query(q => 
                    q.Regexp(
                        (f) => f.Value(startsWith).OnField(onF => onF.Name)))
                .Take(20)
                );

            Func<ISearchResponse<ESEntities.Company>> query2 = () => this._client.Search<ESEntities.Company>(s => s
             .Index("dsrsystem")
             .SortAscending(sort => sort.Name)
             .Query(q =>
                 q.Regexp(
                     (f) => f.Value(containsNotStartWith).OnField(onF => onF.Name)))
             .Take(20)
             );



            queryResult.StartsWith = Execute(query1);

            queryResult.Contains = Execute(query2);

          

            queryResult.Duration = queryResult.StartsWith.Duration + queryResult.Contains.Duration;
            queryResult.Discriminator = discriminator;

            return queryResult;
        }

        private static CompanySearchConsole.MongoEntities.PartialResult Execute(Func<ISearchResponse<ESEntities.Company>> query, string info = "")
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();

            var queryResult = query();

            watch.Stop();

            var cursor = "";
            var n = queryResult.Total;
            var nscanned = -1;
            var scanAndOrder = false;

            var duration = queryResult.ElapsedMilliseconds;


            var result = new CompanySearchConsole.MongoEntities.PartialResult { Duration = duration, Count = (int)n, Info = info, Cursor = cursor, NScanned = nscanned, ScanAndOrder = scanAndOrder };
            result.MeasuredDuration = watch.ElapsedMilliseconds;

            return result;
        }

    }
}
